"""
Вспомогательные команжы для работы с движком ВК.

Команды в основном предназначены для администраторов Чио.
Будет очень полезен, если вы используете движк ВК.
- Узнать id пользователей/чата (относительно Чио).
- Управление чёрным списком чатов/пользователей.
- Управление администраторами Чио.
- Выполнение команды от имени другого пользователя.
- Выполнения команды в другом чате.

Author: Milinuri Nirvalen
Ver: 1.8.5 (15)
"""

from chiori import Plugin, Config, Ui
from libs.vk import get_id, get_profiles, get_ids
from libs.utils import parse_timedelta
import datetime
import time
import aiohttp


p = Plugin(name='vk-utils', backend='vk', admins=True, desc='инструменты для управления движком vk*')


# ##############################
# func:
# ##############################

def autoUnban(config):
	now = round(time.time())
	changed = False

	for k, v in list(config.group_data['banned'].items()):
		if v and now >= v:
			del config.group_data['banned'][k]
			changed = True
	if changed:
		config.save()


# ##############################
# handlers:
# ##############################

@p.eventHandler('init')
async def _(app):
	u = Ui()
	u.form(f'''VK UTILS >>> управление движком для vk
пользователей заблокировано: {len(app.backend.banned)}
чатов заблокировано: {len(app.backend.banned_chats)}''')


@p.eventHandler('before')
async def _(event, ctx):
	autoUnban(Config(ctx.backend.name))


# ##############################
# commands:
# ##############################

@p.command('id', 'uid', 'ids', usage='[target] получить id пользователей', users=True)
async def getUserId(event, ctx):
	ids = await get_ids(event, ctx)
	text = f"id пользователей ({len(ids)}):"

	if ids:
		profiles = await get_profiles(event, ctx, ids)
		for k, v in profiles.items():
			text += f'\n[{k}] {v["name"]}'
	await ctx.message(text)


@p.command('cid', users=True, usage='получить id диалога')
async def getChatId(event, ctx):
	if event.get('to.is_chat'):
		await ctx.message(f'ID чата: {event.get("to.id")-2000000000} ({event.get("to.id")})')
	else:
		await ctx.message(f'ваш ID: {event.get("to.id")}')


@p.command('ban-c', usage='[target] добавить чат в чёрный список')
async def banChat(event, ctx):
	target = ctx.sargs
	if not target:
		target = str(event.get('to.id'))

	c = Config(ctx.backend.name)
	if target not in c.group_data['banned_chats']:
		c.group_data['banned_chats'].append(target)
		c.save()
		await ctx.message(f'<{target}> заблокирован.')
	else:
		await ctx.message(f'<{target}> уже находится в чёрном списке.')


@p.command('unban-c', usage='[target] удалить чат из чёрного списка')
async def unBanChat(event, ctx):
	target = ctx.sargs
	if not target:
		target = str(event.get('to.id'))

	c = Config(ctx.backend.name)
	if target in c.group_data['banned_chats']:
		c.group_data['banned_chats'].remove(target)
		c.save()
		await ctx.message(f'<{target}> разблокирован.')
	else:
		await ctx.message(f'<{target}> не находится в чёрном списке.')


@p.command("ban-u", usage="[targets] добавить пользователя в чёрный список")
async def banUser(event, ctx):
	c = Config(ctx.backend.name)
	targets = await get_ids(event, ctx)
	text = ""

	end_time = parse_timedelta(ctx.sargs)
	if end_time > 0:
		end_time = int(time.time()) + end_time
		t = datetime.datetime.fromtimestamp(end_time).strftime("%c")
		end_time_str = f"\nДо {t}."
	else:
		end_time_str = "Бессрочно."

	if not targets:
		text += "Укажите цели для добавления в чёрный список."
	else:
		text += f"Добавлены в чёрный список - {len(targets)}. {end_time_str}"

	for target in targets:
		c.group_data["banned"][target] = end_time
		text += f"\n-- {target}"

	c.save()
	await ctx.message(text)


@p.command("unban-u", usage="[target] удалить пользователя из чёрного списка.")
async def unbanUser(event, ctx):
	c = Config(ctx.backend.name)
	targets = await get_ids(event, ctx)
	text = ""

	if not targets:
		text = "Укажите цели для разблокировки"

	for target in targets:
		try:
			del c.group_data["banned"][target]
		except KeyError:
			text += f"\n-- <{target}> Нет в чёрном списке."
		else:
			text += f"\n-- <{target}> Разблокирован."

	c.save()
	await ctx.message(text)


@p.command('op', usage='[target] назначить администатором')
async def setOperator(event, ctx):
	c = Config(ctx.backend.name)
	target, args = await get_id(event, ctx, ctx.args)

	if target and target not in c.group_data["admins"]:
		c.group_data['admins'].append(target)
		c.save()
		await ctx.message(f'<{target}> назначен администратором.')
	else:
		await ctx.message(f'нет целей для назначения.')


@p.command('deop', 'unop', usage='[target] снимает с поста администратора')
async def unSetOperator(event, ctx):
	c = Config(ctx.backend.name)
	target, args = await get_id(event, ctx, ctx.args)

	if target and target in c.group_data['admins']:
		c.group_data['admins'].remove(target)
		c.save()
		await ctx.message(f'<{target}> снят с роли администратора.')
	else:
		await ctx.message(f'нет целей для снятия.')


@p.command('banchatlist', 'banclist', 'bannedchats', 'banned-c',
	usage='показать список заблокированый чатов')
async def bannedChatsList(event, ctx):
	c = Config(ctx.backend.name).group_data
	if not c["banned_chats"]:
		await ctx.message(f'нет заблокированных чатов')
	else:
		await ctx.message(f'заблокированные чаты: {", ".join(c["banned_chats"])}')


@p.command('banuserlist', 'banulist', 'bannedusers', 'banned-u',
	usage='показать список заблокированых пользователей')
async def bannedUsersList(event, ctx):
	c = Config(ctx.backend.name).group_data
	if c['banned']:
		profiles = await get_profiles(event, ctx, c["banned"])
		text = 'заблокированные пользователи:'
		for k, v in c['banned'].items():
			if v:
				t = datetime.datetime.fromtimestamp(v).strftime("%c")
				text += f'\n-- [{k}] {profiles[k]["name"]} -> {t}'
			else:
				text += f'\n-- [{k}] {profiles[k]["name"]} -> навсегда'
	else:
		text = '-- пусто'
	await ctx.message(text)


@p.command('ops', usage='показать список администраторов бота')
async def operatorsList(event, ctx):
	c = Config(ctx.backend.name).group_data
	if not c["admins"]:
		await ctx.message(f'нет администраторов бота')
	else:
		profiles = await get_profiles(event, ctx, c["admins"])
		text = 'администраторы бота:'
		for k, v in profiles.items():
			text += f'\n-- [{k}] {v["name"]}'

		await ctx.message(text)


@p.command('execute', 'ecmd',
	usage='[target] [cmd] выполнить команду от имени другово пользователя')
async def executeCommand(event, ctx):
	target, args = await get_id(event, ctx, ctx.args)
	if target:
		c = Config(ctx.backend.name).group_data
		e = event
		temp = await ctx.request('messages.getConversationMembers', peer_id=event.get('to.id'))
		if not temp['error']:
			e.model['to']['is_admin'] = True
			is_admin = False
			for u in temp['response']['items']:
				if u['member_id'] == target:
					if 'is_admin' in u:
						is_admin = True
					break
			e.model['from']['is_admin'] = is_admin
		else:
			e.model['to']['is_admin'] = False

		if int(target) > 0:
			resp = await ctx.request('users.get', user_ids=target)
			user = resp['response'][0]
			e.model['from']['first_name'] = user['first_name']
			e.model['from']['last_name'] = user['last_name']
		else:
			e.model['from']['is_mechanism'] = True

		e.model['from']['id'] = target
		e.model['text'] = args
		e = ctx.backend.setLevel(e, c)
		await ctx.app.messageEvent(e)


@p.command('remote',
	usage='[chat_id] выполнить команду в указанном чате')
async def remoteExecuteCommand(event, ctx):
	if ctx.args:
		text = [ctx.args[0], ' '.join(ctx.args[1:])]
		p.log(text)

		e = event
		temp = await ctx.request('messages.getConversationMembers',
			peer_id=text[0])

		if not temp['error']:

			e.set('to.is_admin', True)
			for u in temp['response']['items']:
				if u['member_id'] == event.get('from.id'):
					if 'is_admin' in u:
						e.set('from.is_admin', True)
					break

		e.set('from.username', '')
		e.set('from.first_name', '')
		e.set('from.last_name', '')

		e.set('to.is_chat', True)
		e.set('to.id', text[0])
		e.set('text', text[1])
		await ctx.app.messageEvent(e, True)


# /executechat 2000000006 /warn @youaremylol
